# -*- coding: utf-8 -*-
from __future__ import absolute_import, unicode_literals
import celery
from celery import shared_task
import cx_Oracle
from cron import models as cron_models
from cron.sms import sms
import random
import time
import paramiko
import sys


# def task_batch():
#     batch_id = cron_models.oratk_cron_exec_info.objects.all().order_by('-id').values('id').first()
#     batch_id = batch_id['id']
#     return batch_id

@shared_task
def add(x, y):
    return x + y


@shared_task
def mul(x, y):
    return x * y

@shared_task
def task_args_1(x):
    task_point = x
    sql = cron_models.oratk_cron_point_info.objects.filter(name=task_point).first()
    # db = cx_Oracle.connect('dbmonitor', 'ghsdbmon1tor', select_conn_string.split('=')[1])
    db = cx_Oracle.connect('dbmonitor', 'ghsdbmon1tor', '10.1.3.128:1521/wmstest')
    cursor = db.cursor()
    ##执行sql
    cursor.execute(sql.sqltext)
    ##列名
    columns = [col[0] for col in cursor.description]
    # print (columns)
    ##一条记录为一个字典,结果集为列表
    # cursor.rowfactory = lambda *args: dict(zip(columns, args))
    ##获取结果
    sql_result = cursor.fetchall()
    if sql_result[0][0] != 1:
        pass
    return sql_result


@shared_task
def task_args_limit(x,y):
    return x * y
#关键字参数-任务
@shared_task
def task_kwargs(**kwargs):
    ##kwargs参数
    global sms_contact
    ##批次号,来标记同一个任务 batch_id
    global batch_id
    batch_id = random.sample(range(0, 999999),1)[0]
    task_name = kwargs['task_name']
    point_name = kwargs['point_name']
    limit_status = kwargs['limit_status']
    limit = kwargs['limit']
    limit_unit = kwargs['limit_unit']
    sms_status = kwargs['sms_status']
    sms_conent = kwargs['sms_conent']
    sms_contact = kwargs['sms_contact']
    email_contact = kwargs['email_contact']
    add_ins = kwargs['ins']
    #获取当前时间
    curr_time = time.strftime('%Y-%m-%dT%H:%M:%S', time.localtime(time.time()))
    #获取短信联系人
    iphone_list = [c.split('__')[1] for c in sms_contact]
    sms_contact = ",".join(iphone_list)
    for ins in add_ins:
        ins_string = ins.split('__',1)[1]
        db_name = ins.split('__',1)[0]
        print(ins_string)
        try:
            print(222)
            db = cx_Oracle.connect('dbmonitor', 'ghsdbmon1tor', ins_string)
            cursor = db.cursor()
            sql = cron_models.oratk_cron_point_info.objects.filter(name=point_name).first()
            #执行sql
             #判断是否有阀值
            if str(limit_status) == '0':
                print(333)
                cursor.execute(sql.sqltext)
                columns = [col[0] for col in cursor.description]
                sql_result = cursor.fetchall()
                ##将任务执行结果插入表中
                if sql_result:
                    #短信内容
                    sms_conent = curr_time +', DB: '+db_name+', MSG: ' + str(sql_result) + ', INS: '+ins_string
                    if str(sms_status) == '1':
                        ##将任务执行结果插入表中
                        cron_models.oratk_cron_exec_info.objects.create(task_batch=batch_id,task_name=task_name,instance=ins_string, point_name=point_name,
                                                                         sql_result=sql_result,sms_info='发送短信',remake='任务执行正常,触发预警')
                        sms(task_name=task_name, reciever=sms_contact, message=sms_conent)
                        print (task_name, point_name, sms_status, sms_conent, sms_contact,'任务执行正常,触发预警')
                    else:
                        ##将任务执行结果插入表中
                        cron_models.oratk_cron_exec_info.objects.create(task_batch=batch_id,task_name=task_name, point_name=point_name,instance=ins_string,
                                                                         sql_result=sql_result,sms_info='未发送短信',remake='该任务短信功能已关闭')
                        print (task_name, point_name, sms_status, sms_conent, sms_contact, '任务执行正常,触发预警,该任务短信功能已关闭')
                ##sql执行无结果-->记录任务执行信息-->不发短信
                else:
                    ##将任务执行结果插入表中
                    cron_models.oratk_cron_exec_info.objects.create(task_batch=batch_id,task_name=task_name, point_name=point_name,instance=ins_string,
                                                                    limit_status=limit_status, limit=limit,limit_unit=limit_unit,
                                                                    sql_result=sql_result, remake='任务执行正常,未触发预警')
                    print (task_name, point_name, '任务执行正常,未触发预警')
            if str(limit_status) == '1':
                print(444)
                sql_limit = sql.sqltext.replace(":limit",limit)
                ##执行sql
                cursor.execute(sql_limit)
                print (sql_limit)
                ##结果集列名
                columns = [col[0] for col in cursor.description]
                ##结果集
                sql_result = cursor.fetchall()

                ##sql执行有结果--->记录任务执行信息-->发短信
                if sql_result:
                    print(555)
                    #短信内容
                    print(limit_unit)
                    sms_conent = curr_time +', DB: '+db_name+ ', MSG: ' + str(sql_result) + ', limit:' + limit+limit_unit+' ,INS:'+ins_string
                    if str(sms_status) == '1':
                        print(666)
                        ##将任务执行结果插入表中
                        cron_models.oratk_cron_exec_info.objects.create(task_batch=batch_id,task_name=task_name,instance=ins_string, point_name=point_name,
                                                                         limit_status=limit_status, limit=limit,limit_unit=limit_unit,
                                                                         sql_result=sql_result,sms_info='发送短信',remake='任务执行正常,触发预警')
                        sms(task_name=task_name, reciever=sms_contact, message=sms_conent)
                        print (task_name, point_name, limit_status, limit, sms_status, sms_conent, sms_contact,'任务执行正常,触发预警')
                    else:
                        ##将任务执行结果插入表中
                        cron_models.oratk_cron_exec_info.objects.create(task_batch=batch_id,task_name=task_name, point_name=point_name,instance=ins_string,
                                                                         limit_status=limit_status, limit=limit,limit_unit=limit_unit,
                                                                         sql_result=sql_result,sms_info='未发送短信',remake='该任务短信功能已关闭')
                        print (task_name, point_name, limit_status, limit, sms_status, sms_conent, sms_contact, '任务执行正常,触发预警,该任务短信功能已关闭')
                ##sql执行无结果-->记录任务执行信息-->不发短信
                else:
                    ##将任务执行结果插入表中
                    cron_models.oratk_cron_exec_info.objects.create(task_batch=batch_id,task_name=task_name, point_name=point_name,instance=ins_string,
                                                                    limit_status=limit_status, limit=limit,limit_unit=limit_unit,
                                                                    sql_result=sql_result, remake='任务执行正常,未触发预警')
                    print (task_name, point_name, '任务执行正常,未触发预警')

    ##sqlplus   执行异常     sql 执行异常
        except cx_Oracle.DatabaseError as msg:
            print('expcept')
            error, = msg.args
            #获取sql执行失败时的错误信息  #err cx_oracle 返回的报错
            err_msg = error.message
            #检查是否发送短信
            if point_name == 'active_db':
                ##在sql执行异常时,只有当检查项为:active_db时,才会发送短信,其他监控项执行sql异常时只会记录任务执行情况,不会发送短信.
                if str(sms_status) == '1':
                    ##将任务执行情况插入数据库
                    cron_models.oratk_cron_exec_info.objects.create(task_batch=batch_id,task_name=task_name, point_name=point_name,instance=ins_string,
                                                                    limit_status=limit_status, limit=limit,limit_unit=limit_unit,
                                                                    error_msg=err_msg,sms_info='短信已发送')
                    sms_conent =curr_time+', DB: '+db_name+ ', MSG: '+'数据库不可用'+', ERR: "'+err_msg+'" ,INS:'+ins_string
                    sms(task_name=task_name, reciever=sms_contact, message=sms_conent)
                    print (error.message,'短信已发送')
                else:
                    cron_models.oratk_cron_exec_info.objects.create(task_batch=batch_id,task_name=task_name, point_name=point_name,instance=ins_string,
                                                                    limit_status=limit_status, limit=limit,limit_unit=limit_unit,
                                                                    error_msg=err_msg,sms_info='短信未发送',remake='该任务短信功能已关闭')
                    print (error.message,'未发送短信,该任务短信开关已关')
            else:
                cron_models.oratk_cron_exec_info.objects.create(task_batch=batch_id,task_name=task_name, point_name=point_name,instance=ins_string,
                                                                limit_status=limit_status, limit=limit,limit_unit=limit_unit,
                                                                error_msg=err_msg, sms_info='短信未发送', remake='非active_db监控,sql执行异常,不发送短信')
                print (error.message,'非active_db监控,sql执行异常')
        except Exception as err:
            err_info = '此任务出现未知错误,请查看任务日志-',err
            cron_models.oratk_cron_exec_info.objects.create(task_batch=batch_id, task_name=task_name,
                                                            point_name=point_name, instance=ins_string,
                                                            limit_status=limit_status, limit=limit,limit_unit=limit_unit,error_msg=err,
                                                            remake=err_info)
            print(err_info)



@shared_task
def task_kwargs_host_cpu(**kwargs):
    ##kwargs参数
    global sms_contact
    ##批次号,来标记同一个任务 batch_id
    global batch_id
    batch_id = random.sample(range(0, 999999),1)[0]
    task_name = kwargs['task_name']
    point_name = kwargs['point_name']
    limit_status = kwargs['limit_status']
    limit = kwargs['limit']
    limit_unit = kwargs['limit_unit']
    sms_status = kwargs['sms_status']
    sms_conent = kwargs['sms_conent']
    sms_contact = kwargs['sms_contact']
    email_contact = kwargs['email_contact']
    add_ins = kwargs['ins']
    #获取当前时间
    curr_time = time.strftime('%Y-%m-%dT%H:%M:%S', time.localtime(time.time()))
    #获取短信联系人
    iphone_list = [c.split('__')[1] for c in sms_contact]
    sms_contact = ",".join(iphone_list)
    sql = cron_models.oratk_cron_point_info.objects.filter(name=point_name).first()
    for ins in add_ins:
        host_name = ins.split('__', 2)[0]
        host_ip = ins.split('__',2)[1]
        host_port = ins.split('__',2)[2]
        host_ins_string = ins.split('__',1)[1]
        try:
            ##ssh连接
            client = paramiko.SSHClient()
            client.set_missing_host_key_policy(paramiko.AutoAddPolicy())
            client.connect(hostname=host_ip, port=host_port, username='monitor', password='ghsmon1tor')
            cpu = sql.sqltext
            stdin, stdout, stderr = client.exec_command(cpu)
            cpu_res = stdout.readlines()
            cpu_usage = str(round((100 - (int(cpu_res[0]) + int(cpu_res[1]) + int(cpu_res[2])) / 3), 2)) + '%'
            cpu_usage_value = cpu_usage.split('%')[0]
            res_err = stderr.read().decode('utf-8')
            print(res_err)
            client.close()
                ##sql执行有结果--->记录任务执行信息-->发短信
            resoult = {}
            resoult['name'] = 'cpu'
            resoult['使用率'] = cpu_usage
            print(resoult)
            print(int(float(cpu_usage_value)),int(limit))
            if int(float(cpu_usage_value)) >= int(limit):
                if str(sms_status) == '1':
                    cron_models.oratk_cron_exec_info.objects.create(task_batch=batch_id, task_name=task_name,
                                                                    instance=host_ins_string, point_name=point_name,
                                                                    limit_status=limit_status, limit=limit,limit_unit=limit_unit,
                                                                    sql_result=resoult, sms_info='发送短信',
                                                                    remake='任务执行正常,触发预警')
                    sms_conent = curr_time + ', name: ' + host_name + ', MSG: ' + str(resoult) + ', limit: "' + limit + limit_unit+ '" ,INS:' + host_ins_string
                    sms(task_name=task_name, reciever=sms_contact, message=sms_conent)
                    print(task_name,point_name,'任务执行正常,触发预警')
                else:
                    cron_models.oratk_cron_exec_info.objects.create(task_batch=batch_id, task_name=task_name,
                                                                    instance=host_ins_string, point_name=point_name,
                                                                    limit_status=limit_status, limit=limit,limit_unit=limit_unit,
                                                                    sql_result=resoult, sms_info='未发送短信',
                                                                    remake='该任务短信功能已关闭')
                    print(task_name,point_name,'短信功能关闭')
            ##sql执行无结果-->记录任务执行信息-->不发短信
            else:
                ##将任务执行结果插入表中
                cron_models.oratk_cron_exec_info.objects.create(task_batch=batch_id, task_name=task_name,
                                                                instance=host_ins_string, point_name=point_name,
                                                                limit_status=limit_status, limit=limit,limit_unit=limit_unit,
                                                                sql_result=resoult,
                                                                remake='任务执行正常,未触发预警')
                print (task_name, point_name, '任务执行正常,未触发预警')

        except Exception as err:
            print(err)
            cron_models.oratk_cron_exec_info.objects.create(task_batch=batch_id, task_name=task_name,
                                                            instance=host_ins_string, point_name=point_name,
                                                            limit_status=limit_status, limit=limit,limit_unit=limit_unit,error_msg=err,
                                                            remake='任务执行发生异常')
            print(task_name, point_name, '任务执行发生异常')



@shared_task
def task_kwargs_host_disk(**kwargs):
    ##kwargs参数
    global sms_contact
    ##批次号,来标记同一个任务 batch_id
    global batch_id
    batch_id = random.sample(range(0, 999999),1)[0]
    task_name = kwargs['task_name']
    point_name = kwargs['point_name']
    limit_status = kwargs['limit_status']
    limit = kwargs['limit']
    limit_unit = kwargs['limit_unit']
    sms_status = kwargs['sms_status']
    sms_conent = kwargs['sms_conent']
    sms_contact = kwargs['sms_contact']
    email_contact = kwargs['email_contact']
    add_ins = kwargs['ins']
    #获取当前时间
    curr_time = time.strftime('%Y-%m-%dT%H:%M:%S', time.localtime(time.time()))
    #获取短信联系人
    iphone_list = [c.split('__')[1] for c in sms_contact]
    sms_contact = ",".join(iphone_list)
    sql = cron_models.oratk_cron_point_info.objects.filter(name=point_name).first()
    for ins in add_ins:
        host_name = ins.split('__', 2)[0]
        host_ip = ins.split('__',2)[1]
        host_port = ins.split('__',2)[2]
        host_ins_string = ins.split('__',1)[1]
        try:
            ##ssh连接
            client = paramiko.SSHClient()
            client.set_missing_host_key_policy(paramiko.AutoAddPolicy())
            client.connect(hostname=host_ip, port=host_port, username='monitor', password='ghsmon1tor')
            disk = sql.sqltext
            stdin, stdout, stderr = client.exec_command(disk)
            ##命令执行结果,readlines是将结果弄成列表方式
            disk_res = stdout.readlines()
            print(disk_res)
            #disk_usage = str(round((100 - (int(disk_res[0]) + int(disk_res[1]) + int(disk_res[2])) / 3), 2)) + '%'
            #pu_usage_value = disk_usage.split('%')[0]
            res_err = stderr.read().decode('utf-8')
            print(res_err)
            client.close()
            #将结果转成字典{1: {'dir': '/dev/sda1', '使用率': '21%\n'}, 2: {'dir': 'tmpfs', '使用率': '1%\n'}, 3: {'dir': '/dev/sdb1', '使用率': '11%\n'}, 4: {'dir': '/dev/sda2', '使用率': '95%\n'}}
            resoult_1 = {}
            resoult_2 = {}
            i = 1
            for list_val in disk_res:
                dir = list_val.split(' ')[0]
                rate = list_val.split(' ')[1].split('\n')[0]
                resoult_1[i] = {'dir': dir, '使用率': rate}
                if int(float(rate.split('%')[0])) > int(limit):
                    resoult_2[i] = {'dir':dir,'使用率':rate}
                i = i+1
            print(resoult_1)
            print(resoult_2)
            print(len(resoult_2))
            if len(resoult_2) >= 1:
                if str(sms_status) == '1':
                    cron_models.oratk_cron_exec_info.objects.create(task_batch=batch_id, task_name=task_name,
                                                                    instance=host_ins_string, point_name=point_name,
                                                                    limit_status=limit_status, limit=limit,limit_unit=limit_unit,
                                                                    sql_result=resoult_2, sms_info='发送短信',
                                                                    remake='任务执行正常,触发预警')
                    sms_conent = curr_time + ', name: ' + host_name + ', MSG: ' + str(resoult_2) + ', limit: ' + limit + limit_unit+' ,INS:' + host_ins_string
                    sms(task_name=task_name, reciever=sms_contact, message=sms_conent)
                    print(task_name,point_name,'任务执行正常,触发预警')
                else:
                    cron_models.oratk_cron_exec_info.objects.create(task_batch=batch_id, task_name=task_name,
                                                                    instance=host_ins_string, point_name=point_name,
                                                                    limit_status=limit_status, limit=limit,limit_unit=limit_unit,
                                                                    sql_result=resoult_2, sms_info='未发送短信',
                                                                    remake='该任务短信功能已关闭')
                    print(task_name,point_name,'短信功能关闭')
            ##sql执行无结果-->记录任务执行信息-->不发短信
            else:
                ##将任务执行结果插入表中
                cron_models.oratk_cron_exec_info.objects.create(task_batch=batch_id, task_name=task_name,
                                                                instance=host_ins_string, point_name=point_name,
                                                                limit_status=limit_status, limit=limit,limit_unit=limit_unit,
                                                                sql_result=resoult_1,
                                                                remake='任务执行正常,未触发预警')
                print (task_name, point_name, '任务执行正常,未触发预警')

        except Exception as err:
            print(err)
            cron_models.oratk_cron_exec_info.objects.create(task_batch=batch_id, task_name=task_name,
                                                            instance=host_ins_string, point_name=point_name,
                                                            limit_status=limit_status, limit=limit,limit_unit=limit_unit,error_msg=err,
                                                            remake='任务执行发生异常')
            print(task_name, point_name, '任务执行发生异常')

@shared_task
def task_kwargs_host_mem(**kwargs):
    ##kwargs参数
    global sms_contact
    ##批次号,来标记同一个任务 batch_id
    global batch_id
    batch_id = random.sample(range(0, 999999),1)[0]
    task_name = kwargs['task_name']
    point_name = kwargs['point_name']
    limit_status = kwargs['limit_status']
    limit = kwargs['limit']
    limit_unit = kwargs['limit_unit']
    sms_status = kwargs['sms_status']
    sms_conent = kwargs['sms_conent']
    sms_contact = kwargs['sms_contact']
    email_contact = kwargs['email_contact']
    add_ins = kwargs['ins']
    #获取当前时间
    curr_time = time.strftime('%Y-%m-%dT%H:%M:%S', time.localtime(time.time()))
    #获取短信联系人
    iphone_list = [c.split('__')[1] for c in sms_contact]
    sms_contact = ",".join(iphone_list)
    sql = cron_models.oratk_cron_point_info.objects.filter(name=point_name).first()
    for ins in add_ins:
        host_name = ins.split('__', 2)[0]
        host_ip = ins.split('__',2)[1]
        host_port = ins.split('__',2)[2]
        host_ins_string = ins.split('__',1)[1]
        try:
            ##ssh连接
            client = paramiko.SSHClient()
            client.set_missing_host_key_policy(paramiko.AutoAddPolicy())
            client.connect(hostname=host_ip, port=host_port, username='monitor', password='ghsmon1tor')
            mem = sql.sqltext
            stdin, stdout, stderr = client.exec_command(mem)
            mem_res = stdout.readlines()
            mem_total = round(int(mem_res[0]) / 1024)
            mem_total_free = round(int(mem_res[1]) / 1024) + round(int(mem_res[2]) / 1024) + round(int(mem_res[3]) / 1024)
            mem_swap_total = round(int(mem_res[4]) / 1024)
            mem_swap_total_free = round(int(mem_res[5]) / 1024)
            mem_usage = str(round(((mem_total - mem_total_free) / mem_total) * 100, 2)) + "%"
            mem_swap_usage = str(round(((mem_swap_total - mem_swap_total_free) / mem_total) * 100, 2)) + "%"
            mem_usage_value = mem_usage.split('%')[0]
            mem_swap_usage_value = mem_swap_usage.split('%')[0]
            res_err = stderr.read().decode('utf-8')
            print(res_err)
            client.close()
                ##sql执行有结果--->记录任务执行信息-->发短信
            resoult = {}
            resoult['mem'] = '使用率:'+mem_usage
            resoult['mem_swap'] = '使用率:'+mem_swap_usage
            print(resoult)
            if int(float(mem_usage_value)) >= int(limit):
                if str(sms_status) == '1':
                    cron_models.oratk_cron_exec_info.objects.create(task_batch=batch_id, task_name=task_name,
                                                                    instance=host_ins_string, point_name=point_name,
                                                                    limit_status=limit_status, limit=limit,limit_unit=limit_unit,
                                                                    sql_result=resoult, sms_info='发送短信',
                                                                    remake='任务执行正常,触发预警')
                    sms_conent = curr_time + ', name: ' + host_name + ', MSG: ' + str(resoult) + ', limit: ' + limit  + limit_unit+' ,INS:' + host_ins_string
                    sms(task_name=task_name, reciever=sms_contact, message=sms_conent)
                    print(task_name,point_name,'任务执行正常,触发预警')
                else:
                    cron_models.oratk_cron_exec_info.objects.create(task_batch=batch_id, task_name=task_name,
                                                                    instance=host_ins_string, point_name=point_name,
                                                                    limit_status=limit_status, limit=limit,limit_unit=limit_unit,
                                                                    sql_result=resoult, sms_info='未发送短信',
                                                                    remake='该任务短信功能已关闭')
                    print(task_name,point_name,'短信功能关闭')
            ##sql执行无结果-->记录任务执行信息-->不发短信
            else:
                ##将任务执行结果插入表中
                cron_models.oratk_cron_exec_info.objects.create(task_batch=batch_id, task_name=task_name,
                                                                instance=host_ins_string, point_name=point_name,
                                                                limit_status=limit_status, limit=limit,limit_unit=limit_unit,
                                                                sql_result=resoult,
                                                                remake='任务执行正常,未触发预警')
                print (task_name, point_name, '任务执行正常,未触发预警')

        except Exception as err:
            print(err)
            cron_models.oratk_cron_exec_info.objects.create(task_batch=batch_id, task_name=task_name,
                                                            instance=host_ins_string, point_name=point_name,
                                                            limit_status=limit_status, limit=limit,limit_unit=limit_unit,error_msg=err,
                                                            remake='任务执行发生异常')
            print(task_name, point_name, '任务执行发生异常')